package com.tataben.annotation;

import java.util.concurrent.ConcurrentHashMap;

/**
 * 双键
 * @author tataben
 * @param <K1>
 * @param <K2>
 * @param <V>
 */
public class DoubleKey<K1, K2, V> {

    private final ConcurrentHashMap<K1, ConcurrentHashMap<K2, V>> k1_k2V_map;

    public ConcurrentHashMap<K2, V> get(K1 key1) {
        return k1_k2V_map.get(key1);
    }

    public DoubleKey() {
        this.k1_k2V_map = new ConcurrentHashMap<>();
    }

    public void remove(K1 key1) {
        k1_k2V_map.remove(key1);
    }

    public void put(K1 key1, K2 key2, V value) {
        if (key1 == null || key2 == null || value == null) return;
        if (k1_k2V_map.containsKey(key1)) {
            ConcurrentHashMap<K2, V> k2V_map = k1_k2V_map.get(key1);
            if (k2V_map != null) {
                k2V_map.put(key2, value);
            } else {
                k2V_map = new ConcurrentHashMap<>();
                k2V_map.put(key2, value);
                k1_k2V_map.put(key1, k2V_map);
            }
        } else {
            ConcurrentHashMap<K2, V> k2V_map = new ConcurrentHashMap<>();
            k2V_map.put(key2, value);
            k1_k2V_map.put(key1, k2V_map);
        }
    }

    public void remove(K1 key1, K2 key2) {
        ConcurrentHashMap<K2, V> k2_v = k1_k2V_map.get(key1);
        if (k2_v != null) {
            k2_v.remove(key2);
        }
        if (k2_v == null || k2_v.isEmpty()) {
            k1_k2V_map.remove(key1);
        }
    }

    public V get(K1 key1, K2 key2) {
        ConcurrentHashMap<K2, V> k2_v = k1_k2V_map.get(key1);
        return k2_v == null ? null : k2_v.get(key2);
    }

    public int size() {
        if (k1_k2V_map.size() == 0) return 0;

        int result = 0;
        for (ConcurrentHashMap<K2, V> k2V_map : k1_k2V_map.values()) {
            result += k2V_map.size();
        }
        return result;
    }
}